/**
 * 
 */
package com.ihome.framework.core.event.command;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ihome.framework.core.event.IHomeEventBusHandler;
import com.ihome.framework.core.event.command.buffer.CommandBuffer.CommandDto;
import com.ihome.framework.core.event.command.buffer.SimpleSqlCommand;

/**
 * @author zww
 *
 */
@Component
public class CommandDispatch implements InitializingBean{

    private CommandProcessor[] processors;

    private Map<Class<?>, CommandProcessor> fromClzCommandProcessor = new HashMap<Class<?>, CommandProcessor>();


    public <T extends CommandDto> void dispatch(T commandDto) throws Exception{
        Class<?> dispatchClz = null;
        for (Class<?> fromClz : fromClzCommandProcessor.keySet()) {
            Class<?> commandClz = commandDto.getClass();
            if(commandDto instanceof SimpleSqlCommand){
                commandClz = ((SimpleSqlCommand)commandDto).getSimpleClass();
            }
            if(fromClz.isAssignableFrom(commandClz)){
                dispatchClz = fromClz;
                fromClzCommandProcessor.get(fromClz).process(commandDto);
            }
        }
        Assert.isNotNull(dispatchClz,"not find command"+commandDto+" processor... ");
    }

    /* (non-Javadoc)
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        for (CommandProcessor commandProcessor : processors) {
            Class<?> fromClz = IHomeEventBusHandler.getSuperInterfacesActualTypeArguments(commandProcessor.getClass(),0, 0);
            fromClzCommandProcessor.put(fromClz, commandProcessor);
        }
    }

    /**
     * @param processors the processors to set
     */
    @Autowired
    public void setProcessors(CommandProcessor[] processors) {
        this.processors = processors;
    }




}
